package core;

import gui.GUITile;

import java.awt.Point;
import java.util.ArrayList;
import java.util.List;

import card.Card;

/**
 * 
 * @author antongr
 * Handles map operations, being Tile conversion to and from Id,
 */
public class MapUtil {
	
	private static Core core = Core.getInstance();
	
	public static GUITile[][] getGUIMap(){
		Tile[][] map=core.getMap();
		GUITile[][] guiMap = new GUITile[Constants.MAPSIZE][Constants.MAPSIZE];
		for(int x=0; x<Constants.MAPSIZE; x++){
			for(int y=0; y<Constants.MAPSIZE; y++){
				if(withinBorders(new Point(x,y)))				
					guiMap[x][y]=new GUITile(map[x][y], new Point(x, y), true);
				else
					guiMap[x][y]=new GUITile(map[x][y], new Point(x, y), false);
			}
		}
		return guiMap;
	}
	
	/**
	 * checks if the coordinate p is within the accepted borders of the map
	 * @param p
	 * @return
	 */
	public static boolean withinBorders(Point p){
		if (p.x+p.y > Constants.MAPSIZE/2-1 && p.x+p.y < Constants.MAPSIZE/2*3+1)
			return true;
		else
			return false;
	}
	
	/**
	 * returns the Tile on which the given card is placed.
	 * returns null if the card is not on the gameboard.
	 * @param c
	 * @return
	 */
	public static Tile getTileOfCard(Card card){
		for(int x=0; x<Constants.MAPSIZE; x++){
			for(int y=0; y<Constants.MAPSIZE; y++){
				if(core.map[x][y].contains(card))
					return core.map[x][y];
			}
		}
		return null;
	}
	
	public static int getIdOfTile(Tile t){
		for(int x=0; x<Constants.MAPSIZE; x++){
			for(int y=0; y<Constants.MAPSIZE; y++){
				if(core.map[x][y]==t)
					return x+y*Constants.MAPSIZE;
			}
		}
		return -1;
	}
	
	public static Tile getTile(Point p){
		return core.map[p.x][p.y];
	}
	
	public static Tile getTile(int id){
		return core.map[id%Constants.MAPSIZE][id/Constants.MAPSIZE];
	}
	
	/**
	 * Returns a list of all tiles owned by the given player.
	 * @param owner
	 * @return
	 */
	public static List<Tile> getTiles(Player owner){
		List<Tile> returnList = new ArrayList<Tile>();
		for(int x=0; x<Constants.MAPSIZE; x++){
			for(int y=0; y<Constants.MAPSIZE; y++){
				if(core.map[x][y].getOwningPlayer()==owner){
					returnList.add(core.map[x][y]);
				}
			}
		}
		return returnList;
	}
	
	/**
	 * Used for finding if the Tile is in place (2,4) or such
	 * @param t
	 * @return The coordinates of the Tile's position on the map.
	 */
	public static Point getPosition(Tile t){
		int id = getIdOfTile(t);
		int x=id%Constants.MAPSIZE;
		int y=id/Constants.MAPSIZE;
		return new Point(x, y);
	}
	
	/**
	 * Used for finding if the GUITile is in place (2,4) or such
	 * @param t
	 * @return The coordinates of the GUITile's position on the map.
	 */
	public static Point getPosition(GUITile t){
		return getPosition(t.getTile());
	}
	
	/**
	 * Uses an algorithm that lets Dx take priority over Dy.
	 * @param t1
	 * @param t2
	 * @return The number of steps that needs to be taken to get from t1 to t2, without obstacles.
	 * 
	 */
	public static int getRange(Tile t1, Tile t2){
		Point p1, p2;
		p1=getPosition(t1);
		p2=getPosition(t2);
		int dx = (p1.x-p2.x);
		int dy = (p1.y-p2.y);
		int range = 0;
		while(dx!=0 || dy != 0){
			
			if(dx<0){
				dx++;
				if(dy>0)
					dy--;				
			}
			else if(dx>0){
				dx--;
				if(dy<0)
					dy++;
			}
			else{ //dx==0
				if(dy<0)
					dy++;
				else if(dy>0)
					dy--;
			}
			range++;		
		}		
		return range;
	}

}
